package com.own.component.token.core;

import com.own.component.autoconfig.property.token.TokenPolicy;
import com.own.component.autoconfig.property.token.TokenProperty;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
 * TokenRuleManager
 *
 * @author chenxueli
 * @date 2023-08-10 16:47:18
 */
@Slf4j
@Component
public class TokenRuleManager {

    private static final Map<String, TokenRule> TOKEN_RULE_MAP = new HashMap<>(16);
    private static TokenRule DEFAULT_TOKEN_RULE;

    @Resource
    private TokenProperty tokenProperty;

    /**
     * 获取规则信息
     *
     * @param client 客户端名称
     * @return 配置信息
     */
    public static TokenRule get(String client) {
        return TOKEN_RULE_MAP.getOrDefault(client, DEFAULT_TOKEN_RULE);
    }

    /**
     * 获取所有的客户端名称
     *
     * @return 客户端名称列表
     */
    public static Set<String> clientArray() {
        return TOKEN_RULE_MAP.keySet();
    }

    @PostConstruct
    public void init() {
        for (var client : tokenProperty.getClientArray()) {
            put(client, tokenProperty.getPolicy(), tokenProperty.getTimeout(), tokenProperty.getAutoLoginEffectiveTime(), tokenProperty.getAutoLoginTimeout());
        }
        put(tokenProperty.getDefaultClient(), tokenProperty.getPolicy(), tokenProperty.getTimeout(), tokenProperty.getAutoLoginEffectiveTime(), tokenProperty.getAutoLoginTimeout());
        var multiple = tokenProperty.getMultiple();
        if (multiple != null && !multiple.isEmpty()) {
            multiple.forEach((key, value) -> put(
                    key,
                    value.getPolicy(),
                    value.getTimeout(),
                    value.getAutoLoginEffectiveTime(),
                    value.getAutoLoginTimeout()
            ));
        }
        DEFAULT_TOKEN_RULE = TOKEN_RULE_MAP.get(tokenProperty.getDefaultClient());
    }

    /**
     * 添加规则信息
     *
     * @param client                 客户端名称
     * @param policy                 策略信息
     * @param timeout                超时时间信息
     * @param autoLoginEffectiveTime 自动登录开始生效的时间
     * @param autoLoginTimeout       自动登录超时时间
     */
    private void put(
            String client,
            TokenPolicy policy,
            Long timeout,
            Long autoLoginEffectiveTime,
            Long autoLoginTimeout
    ) {
        if (TOKEN_RULE_MAP.containsKey(client)) {
            return;
        }
        TOKEN_RULE_MAP.put(client, TokenRule
                .builder()
                .name(client)
                .timeout(timeout)
                .autoLoginEffectiveTime(autoLoginEffectiveTime)
                .autoLoginTimeout(autoLoginTimeout)
                .policy(policy)
                .build()
        );
    }

}
